#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <unistd.h>

// #include "Tcpserver.hpp"
//! 头文件不能相互包含

class Connection; // 前置声明
class TcpServer;

using func_t = std::function<void(Connection *)>;

class Connection
{
    int _sockfd; // 对应的 sockfd

    std::string _inbuffer;  // 接收缓冲区
    std::string _outbuffer; // 发送缓冲区

    // 关系的事件
    uint32_t _events;

    // 维护 client 的ip 和 port 信息
    // struct sockaddr_in _client;

public:
    // 对 connection 进行处理的回调函数
    func_t _recver;   // 接收
    func_t _sender;   // 发送F
    func_t _excepter; // 出错处理

    // TcpServer 的回调指针
    TcpServer *R;

public:
    Connection(int sockfd, int32_t event, TcpServer *tcp_server) : _sockfd(sockfd), _events(event), R(tcp_server)
    {
    }

    ~Connection()
    {
    }

    // void SetClient(const struct sockaddr_in client)
    // {
    //     _client = client;
    // }

    void RegisterFunc(func_t recver, func_t sender, func_t excepter)
    {
        _recver = recver;
        _sender = sender;
        _excepter = excepter;
    }

    void AddInbuffer(std::string buffer)
    {
        _inbuffer += buffer; // 加入读取缓冲区
    }

    bool OutBufferEmpty()
    {
        return _outbuffer.empty();
    }

    void AddOutBuffer(const std::string &buffer)
    {
        _outbuffer += buffer;
    }

    int Sockfd()
    {
        return _sockfd;
    }

    void SetEvents(uint32_t events)
    {
        _events = events;
    }

    std::string &InBuffer()
    {
        return _inbuffer;
    }

    std::string &OutBuffer()
    {
        return _outbuffer;
    }

    uint32_t Events()
    {
        return _events;
    }

    void Close()
    {
        close(_sockfd);
    }
};

class ConnectionFactory
{
public:
    static Connection *BuildListenConnection(int listensock, func_t recver, uint32_t events, TcpServer *tcp_server)
    {
        Connection *conn = new Connection(listensock, events, tcp_server);
        // 创建连接,注册读方法 , 写方法和出错不关心
        conn->RegisterFunc(recver, nullptr, nullptr);
        return conn;
    }

    static Connection *BuildNormalConnection(int sockfd, func_t recver, func_t sender, func_t excepter, uint32_t events, TcpServer *tcp_server)
    {
        Connection *conn = new Connection(sockfd, events, tcp_server);

        // 注册 普通套接字的方法
        conn->RegisterFunc(recver, sender, excepter);
        return conn;
    }
};